package com.jhws.common.pay.api;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayMobilePublicMultiMediaClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.jhws.business.customer.bo.PayCustomerSecret;
import com.jhws.business.customer.service.PayCustService;
import com.jhws.common.base.bo.JsonRespData;
import com.jhws.common.pay.utils.weixinAes.WXBizMsgCrypt;
import com.jhws.sys.user.bo.TblUserDimBo;
import com.jhws.sys.user.service.ITblUserDimService;
import com.jhws.util.*;
import com.jhws.common.PropertiesReader;
import com.jhws.common.pay.bo.Order;
import com.jhws.common.pay.bo.PayConstants;
import com.jhws.common.pay.service.OrderService;
import com.jhws.common.pay.service.WXPayService;
import com.jhws.util.net.JhHttpClient;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.*;

@Controller
@RequestMapping("/v2/pay")
public class payApiV2 {


    private String notifyUrl = (StringUtils.isEmpty(PropertiesReader.getProperty("basePlatform")) ? "" : PropertiesReader.getProperty("basePlatform") + '.') + "jhws.top" + PayConstants.WeixinNotifyUrl;
    private String alipayNotifyUrl = "http://" + (StringUtils.isEmpty(PropertiesReader.getProperty("basePlatform")) ? "" : PropertiesReader.getProperty("basePlatform") + '.') + "jhws.top" + PayConstants.AlipayNotifyUrl;
    private String charset = "UTF-8";

    @Resource
    WXPayService wxPayService;
    @Resource
    OrderService orderService;
    @Resource
    PayCustService IPayCustService;
    @Resource
    RedisTemplate stringTemplate;
    @Resource
    ITblUserDimService IUserService;
    /**
     * 微信APP支付下单
     *
     * @param totalFee  订单总金额
     * @param orderType 订单类型 ，停车场或者物业缴费等
     * @param ownerCode 业主id
     * @param body      订单描述
     * @param attach    订单私有数据
     * @return
     * @throws Exception
     */
    @RequestMapping({"weixin/app/order", "anon/weixin/app/order"})
    @ResponseBody
    public JsonRespData weixinAppOrder(String commCode, String totalFee, String orderType, String ownerCode, String body,
                              String attach, String attach2, String detail, HttpServletRequest request) throws Exception {

        if (StringUtils.isEmpty(totalFee))
            return new JsonRespData("", -1, "请提供订单金额");
        if (StringUtils.isEmpty(orderType))
            return new JsonRespData("", -1, "请提供订单类型");
        if (StringUtils.isEmpty(attach))
            attach = "";


        orderService.moduleLegalAssert(orderType);

        /* 保存临时订单 */
        Order order = new Order();
        order.setId(Long.valueOf(GetId.randomID()));
        order.setAttach(attach);
        order.setAttach2(attach2);
        order.setOrderState(PayConstants.PAY_STATE_UNPAY);
        order.setPayType(PayConstants.PAY_TYPE_WEIXIN_APP);
        order.setOrderType(orderType);
        order.setTime(new Date());
        order.setCommCode(commCode);
        order.setBody(body);
        order.setOwnerCode(ownerCode);
        order.setDetail(detail);
        totalFee = wxPayService.genTotalFee(totalFee);
        order.setTotalFee(String.valueOf(Double.valueOf(totalFee) / 100));
        if (!orderService.orderPreCheck(order))
            return new JsonRespData("", -1, "订单私有参数校验失败");

        PayCustomerSecret customer = orderService.findCustSecretByOrder(order);
        if (customer == null)
            return new JsonRespData("", -1, "未找到相关客户绑定该支付服务!");

        order.setCustomId(customer.getCustomId());

        String appid = customer.getAppId();
        //商户号
        String mch_id = customer.getMchId();
        //随机数
        String nonce_str = wxPayService.genNonceStr();

        //商户订单号
        String out_trade_no = order.getId().toString();

        //订单生成的机器 IP
        String spbill_create_ip = request.getRemoteAddr();
        String trade_type = "APP";//app支付必须填写为APP
        //对以下字段进行签名
        SortedMap<String, String> packageParams = new TreeMap<String, String>();
        packageParams.put("appid", appid);
        packageParams.put("attach", attach);
        packageParams.put("body", body);
        packageParams.put("mch_id", mch_id);
        packageParams.put("nonce_str", nonce_str);
        packageParams.put("notify_url", notifyUrl);
        packageParams.put("out_trade_no", out_trade_no);
        packageParams.put("spbill_create_ip", spbill_create_ip);
        packageParams.put("total_fee", totalFee);
        packageParams.put("trade_type", trade_type);

        String sign = wxPayService.createSign(packageParams, customer.getSecret(), charset);//获取签名
        String xml = "<xml>" +
                "<appid>" + appid + "</appid>" +
                "<attach>" + attach + "</attach>" +
                "<body><![CDATA[" + body + "]]></body>" +
                "<mch_id>" + mch_id + "</mch_id>" +
                "<nonce_str>" + nonce_str + "</nonce_str>" +
                "<notify_url>" + notifyUrl + "</notify_url>" +
                "<out_trade_no>" + out_trade_no + "</out_trade_no>" +
                "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>" +
                "<total_fee>" + totalFee + "</total_fee>" +
                "<trade_type>" + trade_type + "</trade_type>" +
                "<sign>" + sign + "</sign>" +
                "</xml>";

        LogHelper.d(xml);
        String createOrderURL = PayConstants.WeixinCreateOrderURL;
        Map retMap = wxPayService.sendOrderRequest(createOrderURL, xml);
        String prepay_id = (String) retMap.get("prepay_id");
        if (StringUtils.isEmpty(prepay_id)) {
            return new JsonRespData("", -1, "下单失败!");
        }

        order.setPayModule(orderService.getPayModuleName(orderType));
        orderService.save(order);

        //获取到prepayid后对以下字段进行签名最终发送给app
        SortedMap<String, String> finalpackage = new TreeMap<String, String>();
        Long timestamp = DateUtil.getTimeStampsNowFmtSec();
        finalpackage.put("appid", appid);
        finalpackage.put("timestamp", timestamp.toString());
        finalpackage.put("noncestr", nonce_str);
        finalpackage.put("partnerid", mch_id);
        finalpackage.put("package", "Sign=WXPay");
        finalpackage.put("prepayid", prepay_id);
        String finalsign = wxPayService.createSign(finalpackage, customer.getSecret(), charset);
        finalpackage.put("msg", "ok");
        finalpackage.put("sign", finalsign);
        return new JsonRespData("", 1, finalpackage);

    }

    /**
     * 微信公众号支付下单
     *
     * @param totalFee  订单总金额
     * @param orderType 订单类型 ，停车场或者物业缴费等
     * @param body      订单描述
     * @param attach    订单私有数据
     * @param code      从微信授权过来的code, 通过它获取openid, 假如code为空，则判断为H5支付请求，否则为公众号支付请求
     * @return
     * @throws Exception
     */
    @RequestMapping({"weixin/H5/order", "anon/weixin/H5/order"})
    @ResponseBody
    public JsonRespData wexinH5Order(String orderId, String commCode, String ownerCode, String totalFee,String payableFee,
                                String orderType, String body, String attach, String attach2,
                                String code, String detail, HttpServletRequest request) throws Exception {

        if (StringUtils.isEmpty(orderId)) {
            if (StringUtils.isEmpty(totalFee))
                return new JsonRespData("", -1, "请提供订单金额");
            if (StringUtils.isEmpty(orderType))
                return new JsonRespData("", -1, "请提供订单类型");
        }

        if (StringUtils.isEmpty(attach))
            attach = "";

        if (StringUtils.isEmpty(orderId))
            orderService.moduleLegalAssert(orderType);

        Order order;
        /* 已携带订单ID, 为已有订单支付 */
        if (StringUtils.isNotEmpty(orderId)) {
            order = orderService.findOrderById(Long.valueOf(orderId));
            if (order == null)
                return new JsonRespData("", -1, "不存在的订单id:" + orderId);
            totalFee = wxPayService.genTotalFee(order.getTotalFee());
        } else {
        /* 生成临时订单基本信息 */
            order = new Order();
            order.setId(Long.valueOf(GetId.randomID()));
            order.setAttach(attach);
            order.setAttach2(attach2);

            order.setOrderType(orderType);
            order.setTime(new Date());
            order.setCommCode(commCode);
            order.setBody(body);
            order.setDetail(detail);
            order.setOwnerCode(ownerCode);
            totalFee = wxPayService.genTotalFee(totalFee);
            order.setTotalFee(String.valueOf(Double.valueOf(totalFee) / 100));
            order.setPayableFee(payableFee);
        }

        order.setOrderState(PayConstants.PAY_STATE_UNPAY);
        order.setPayType(PayConstants.PAY_TYPE_WEIXIN_H5);

        if (!orderService.orderPreCheck(order))
            return new JsonRespData("", -1, "订单私有参数校验失败");

        PayCustomerSecret customer = orderService.findCustSecretByOrder(order);
        if (customer == null)
            return new JsonRespData("", -1, "未找到相关客户绑定该支付服务!");

        order.setCustomId(customer.getCustomId());
        String appid = customer.getAppId();
        //商户号
        String mch_id = customer.getMchId();
        //随机数
        String nonce_str = wxPayService.genNonceStr();
        //商户订单号
        String out_trade_no = order.getId().toString();

        //订单生成的机器 IP
        String spbill_create_ip = request.getRemoteAddr();
        String trade_type = StringUtils.isNotEmpty(code) ? "JSAPI" : "MWEB";
        //对以下字段进行签名
        SortedMap<String, String> packageParams = new TreeMap<String, String>();
        packageParams.put("appid", appid);
        packageParams.put("attach", order.getAttach());
        packageParams.put("body", order.getBody());
        packageParams.put("mch_id", mch_id);
        packageParams.put("nonce_str", nonce_str);
        packageParams.put("notify_url", notifyUrl);
        packageParams.put("out_trade_no", out_trade_no);
        packageParams.put("spbill_create_ip", spbill_create_ip);
        packageParams.put("total_fee", totalFee);
        packageParams.put("trade_type", trade_type);

        /* 公众号获取openid */
        String openId = "";
        String sceneInfo = "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"https://jhws.top\",\"wap_name\": \"" + order.getOrderType() + "\"}}";
        if (StringUtils.isNotEmpty(code)) {
            openId = wxPayService.getOpenIdBy3rd(appid, code);
            packageParams.put("openid", openId);
        } else
            packageParams.put("scene_info", sceneInfo);

        String sign = wxPayService.createSign(packageParams, customer.getSecret(), charset);//获取签名
        String xml = "<xml>" +
                "<appid>" + appid + "</appid>" +
                "<attach>" + order.getAttach() + "</attach>" +
                "<body><![CDATA[" + order.getBody() + "]]></body>" +
                "<mch_id>" + mch_id + "</mch_id>" +
                "<nonce_str>" + nonce_str + "</nonce_str>" +
                "<notify_url>" + notifyUrl + "</notify_url>" +
                (StringUtils.isNotEmpty(code) ?
                        "<openid>" + openId + "</openid>" :
                        "<scene_info>" + sceneInfo + "</scene_info>"
                ) +
                "<out_trade_no>" + out_trade_no + "</out_trade_no>" +
                "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>" +
                "<total_fee>" + totalFee + "</total_fee>" +
                "<trade_type>" + trade_type + "</trade_type>" +
                "<sign>" + sign + "</sign>" +
                "</xml>";

        LogHelper.d(xml);
        String createOrderURL = PayConstants.WeixinCreateOrderURL;
        Map retMap = wxPayService.sendOrderRequest(createOrderURL, xml);

        /* 获取prepay_id */
        String prepay_id = (String) retMap.get("prepay_id");
        if (StringUtils.isEmpty(prepay_id)) {
            return new JsonRespData("", -1, "下单失败!");
        }

        /* H5支付才有的跳转地址 */
        String MWebUrl = (String) retMap.get("mweb_url");

        order.setPayModule(orderService.getPayModuleName(orderType));
        orderService.save(order);

        //获取到prepayid后对以下字段进行签名最终发送给app
        SortedMap<String, String> finalpackage = new TreeMap<String, String>();
        Long timestamp = DateUtil.getTimeStampsNowFmtSec();
        finalpackage.put("appId", appid);
        finalpackage.put("timeStamp", timestamp.toString());
        finalpackage.put("nonceStr", nonce_str);
        finalpackage.put("signType", "MD5");
        finalpackage.put("package", "prepay_id=" + prepay_id);
        if (StringUtils.isNotEmpty(MWebUrl))
            finalpackage.put("webUrl", MWebUrl);

        String finalsign = wxPayService.createSign(finalpackage, customer.getSecret(), charset);
        finalpackage.put("paySign", finalsign);
        return new JsonRespData("", 1, finalpackage);
    }


    /**
     * 微信异步通知, 通知支付成功
     * 需要校验签名和金额，避免虚假数据
     *
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "anon/weixin/notify")
    @ResponseBody
    public void weixinNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        response.setHeader("Access-Control-Allow-Origin", "*");
        InputStream in = request.getInputStream();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = in.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
        out.close();
        in.close();
        String msgxml = new String(out.toByteArray(), "utf-8");//xml数据
        System.out.println(msgxml);
        Map map = XmlUtils.doXMLParse(msgxml);
        String result_code = (String) map.get("result_code");
        String out_trade_no = (String) map.get("out_trade_no");
        String total_fee = (String) map.get("total_fee");
        String sign = (String) map.get("sign");
        String orderId = out_trade_no.split("\\|")[0];//获取订单编号

        Order order = orderService.findOrderById(Long.valueOf(orderId));
        if (order == null || Double.valueOf(order.getTotalFee()) * 100 != Double.valueOf(total_fee)) {
            response.getWriter().write(setXml("FAIL", "params error"));    //告诉微信签名不对
            LogHelper.d("订单不存在或金额不对!");
            return;
        }

        PayCustomerSecret secret = orderService.findCustSecretByOrder(order);
        if (result_code.equals("SUCCESS")) {
            //验证签名
            SortedMap<String, String> packageParams = new TreeMap<String, String>(map);
            String endsign = wxPayService.createSign(packageParams, secret.getSecret(), charset);
            if (sign.equals(endsign)) {//验证签名是否正确  官方签名工具地址：https://pay.weixin.qq.com/wiki/tools/signverify/
                response.getWriter().write(setXml("SUCCESS", "OK"));    //告诉微信已经收到通知了
                LogHelper.d("签名校验成功!");
                order.setOrderState(PayConstants.PAY_STATE_PAID);
                orderService.save(order);
                orderService.orderPayCallback(order);
            } else {
                response.getWriter().write(setXml("FAIL", "sign error"));    //告诉微信签名不对
                LogHelper.d("签名校验失败!");
            }
        }
    }

    /**
     * 第三方平台的'授权事件接收URL'地址，微信发送ticket过来，用于获取accessToken
     * @param msg_signature  解密需要
     * @param timestamp
     * @param nonce
     * @throws Exception
     */
    @RequestMapping("anon/weixin/3rdAuth/ticket")
    @ResponseBody
    public void weixin3rdAuthTicket(String msg_signature,String timestamp,String nonce,HttpServletRequest request, HttpServletResponse response) throws Exception{
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        response.setHeader("Access-Control-Allow-Origin", "*");
        LogHelper.d(request.getQueryString());
        InputStream in = request.getInputStream();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = in.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
        out.close();
        in.close();
        String msgxml = new String(out.toByteArray(), "utf-8");//xml数据

        WXBizMsgCrypt pc = new WXBizMsgCrypt(PayConstants.Weixin3rdCommServiceMsgToken, PayConstants.Weixin3rdCommServiceMsgCryptKey, PayConstants.Weixin3rdCommServiceAppId);
        LogHelper.d(msgxml);
        String xmlDecrypted = pc.decryptMsg(msg_signature,timestamp,nonce,msgxml,true);
        LogHelper.d(xmlDecrypted);
        Map map = XmlUtils.doXMLParse(xmlDecrypted);

        String ticket = (String)map.get("ComponentVerifyTicket");
        LogHelper.d((String)map.get("ComponentVerifyTicket"));

        stringTemplate.opsForValue().set(PayConstants.REDIS_PAY_WEIXIN_3RD_VERIFY_TICKET,ticket);

        wxPayService.get3rdComponentAccessToken(ticket);
        response.getWriter().write("success");
    }

    /**
     * 微信第三方平台授权后回调URI,接收授权码
     * @return
     */
    @RequestMapping("anon/weixin/3rdAuth/authCode")
    public ModelAndView weixin3rdAuthCode(String auth_code,String expires_in) throws Exception{

        ModelAndView mv = new ModelAndView();
        TblUserDimBo user = IUserService.currentUser();

        JhHttpClient httpClient = new JhHttpClient();
        Map<String,String> dataMap = new HashMap();
        dataMap.put("component_appid",PayConstants.Weixin3rdCommServiceAppId);
        dataMap.put("authorization_code",auth_code);
        String accessToken = wxPayService.get3rdComponentAccessToken(null);
        String result = httpClient.post(PayConstants.WeixinUrl3rdGetRefreshToken+"?component_access_token="+accessToken,GsonUtil.toJson(dataMap));

        LogHelper.d("result :"+result);
        Map map = GsonUtil.toObject(result,Map.class);
        Map authorization_info = (Map)map.get("authorization_info");

        String appId = (String)authorization_info.get("authorizer_appid");
        String authorizerRefreshToken = (String)authorization_info.get("authorizer_refresh_token");

        PayCustomerSecret secret = IPayCustService.findCustSecretByAppId(appId);
        if(secret == null) {
            secret = new PayCustomerSecret();
            secret.setAppId(appId);
            secret.setWxGzhRefreshToken(authorizerRefreshToken);
            secret.setType(PayConstants.PAY_TYPE_WEIXIN_H5);
            secret.setCreator(user.getLogName());
            IPayCustService.save(secret);
        }else if(!user.getLogName().equals(secret.getCreator())){
            PayCustomerSecret secretNew = new PayCustomerSecret();
            secretNew.setMchId(secret.getMchId());
            secretNew.setSecret(secret.getSecret());
            secretNew.setAppId(appId);
            secretNew.setWxGzhRefreshToken(authorizerRefreshToken);
            secretNew.setType(PayConstants.PAY_TYPE_WEIXIN_H5);
            secretNew.setCreator(user.getLogName());
            IPayCustService.save(secretNew);
        }

        mv.addObject("success","true");
        mv.setViewName("/business/pay/weixin3rdAuth");
        return mv;
    }

    public static String setXml(String return_code, String return_msg) {
        return "<xml><return_code><![CDATA[" + return_code + "]]></return_code><return_msg><![CDATA[" + return_msg + "]]></return_msg></xml>";
    }

    @RequestMapping({"alipay/app/order", "anon/alipay/app/order"})
    @ResponseBody
    public JsonRespData toAlipay(String orderId, String commCode, String totalFee, String orderType, String ownerCode, String body, String attach, String attach2,
                                 String detail, HttpServletRequest request) throws Exception {


        if (StringUtils.isEmpty(totalFee))
            return new JsonRespData("", -1, "请提供订单金额");
        if (StringUtils.isEmpty(orderType))
            return new JsonRespData("", -1, "请提供订单类型");
        if (StringUtils.isEmpty(body))
            return new JsonRespData("", -1, "请提供body参数(订单标题)");

        if (StringUtils.isEmpty(attach))
            attach = "";
        orderService.moduleLegalAssert(orderType);

        /* 生成临时订单基本信息 */
        Order order;
        /* 已携带订单ID, 为已有订单支付 */
        if (StringUtils.isNotEmpty(orderId)) {
            order = orderService.findOrderById(Long.valueOf(orderId));
            if (order == null)
                return new JsonRespData("", -1, "不存在的订单id:" + orderId);
        } else {
            order = new Order();
            order.setOwnerCode(ownerCode);
            order.setId(Long.valueOf(GetId.randomID()));
            order.setAttach(attach);
            order.setAttach2(attach2);
            order.setOrderType(orderType);
            order.setTime(new Date());
            order.setCommCode(commCode);
            order.setBody(body);
            order.setDetail(detail);
            order.setTotalFee(totalFee);
        }

        order.setOrderState(PayConstants.PAY_STATE_UNPAY);
        order.setPayType(PayConstants.PAY_TYPE_ALIPAY);

        if (!orderService.orderPreCheck(order))
            return new JsonRespData("", -1, "订单私有参数校验失败");

        PayCustomerSecret customer = orderService.findCustSecretByOrder(order);
        if (customer == null)
            return new JsonRespData("", -1, "未找到相关客户绑定该支付服务!");

        order.setCustomId(customer.getCustomId());

        order.setPayModule(orderService.getPayModuleName(orderType));
        orderService.save(order);
        String appid = customer.getAppId();
        SortedMap<String, String> param = new TreeMap<>();
        param.put("app_id", appid);
        param.put("method", "alipay.trade.app.pay");
        param.put("charset", charset);
        param.put("notify_url", alipayNotifyUrl);
        param.put("version", "1.0");
        param.put("timestamp", DateUtil.getTimeNowFmtSec());
        param.put("sign_type", PayConstants.AlipaySignTypeRSA2);


        // 支付业务请求参数
        SortedMap<String, Object> pcont = new TreeMap<>();
        pcont.put("out_trade_no", order.getId()); // 商户订单号
        pcont.put("total_amount", totalFee);// 交易金额
        pcont.put("subject", body); // 订单标题
        pcont.put("body", attach);// 对交易或商品的描述
        pcont.put("product_code", "QUICK_MSECURITY_PAY");// 销售产品码

        param.put("biz_content", JSON.toJSONString(pcont)); // 业务请求参数  不需要对json字符串转义

        String orderStr = AlipaySignature.getSignContent(param);
        param.put("sign", AlipaySignature.rsaSign(orderStr, customer.getSecret(), charset, PayConstants.AlipaySignTypeRSA2)); // 业务请求参数
        LogHelper.d("signFor " + orderStr);
        orderStr = AlipayMobilePublicMultiMediaClient.buildQuery(param, charset);
        return new JsonRespData("", 1, orderStr);
    }

    private void alipayH5OrderReturn(String msg ,HttpServletResponse response) throws Exception{
        LogHelper.d(msg);
        response.getWriter().write(msg);
        response.setCharacterEncoding("UTF-8");
    }
    /**
     * 支付宝H5支付，采用原生表单提交，直接返回一个支付宝的html页面
     *
     * @throws Exception
     */
    @RequestMapping({"alipay/H5/order", "anon/alipay/H5/order"})
    public void alipayH5Order(String orderId, String commCode, String totalFee, String payableFee, String orderType, String ownerCode,
                              String body, String attach, String attach2, String detail, String returnUrl, HttpServletResponse response) throws Exception {

        response.setCharacterEncoding("UTF-8");
        String retMsg = "";
        if (StringUtils.isEmpty(orderId) && (StringUtils.isEmpty(totalFee) ||
                StringUtils.isEmpty(orderType) || StringUtils.isEmpty(body))) {
            alipayH5OrderReturn("参数错误",response);
            return;
        }
        if (StringUtils.isEmpty(orderId))
            orderService.moduleLegalAssert(orderType);

        /* 生成临时订单基本信息 */
        /* 生成临时订单基本信息 */
        Order order;
        /* 已携带订单ID, 为已有订单支付 */
        if (StringUtils.isNotEmpty(orderId)) {
            order = orderService.findOrderById(Long.valueOf(orderId));

            if (order == null) {
                alipayH5OrderReturn("不存在的订单id:" + orderId,response);
                return;
            }
        } else {
            order = new Order();
            order.setOwnerCode(ownerCode);
            order.setId(Long.valueOf(GetId.randomID()));
            order.setAttach(attach);
            order.setAttach2(attach2);
            order.setOrderType(orderType);
            order.setTime(new Date());
            order.setCommCode(commCode);
            order.setBody(body);
            order.setDetail(detail);
            order.setTotalFee(totalFee);
            order.setPayableFee(payableFee);
        }

        order.setOrderState(PayConstants.PAY_STATE_UNPAY);
        order.setPayType(PayConstants.PAY_TYPE_ALIPAY);

        if (!orderService.orderPreCheck(order)) {
            alipayH5OrderReturn("订单私有参数校验失败",response);
            return;
        }

        PayCustomerSecret customer = orderService.findCustSecretByOrder(order);
        if (customer == null) {
            alipayH5OrderReturn("未找到相关客户绑定该支付服务",response);
            return;
        }

        order.setCustomId(customer.getCustomId());
        order.setPayModule(orderService.getPayModuleName(orderType));
        orderService.save(order);

        // SDK 公共请求类，包含公共请求参数，以及封装了签名与验签，开发者无需关注签名与验签
        //调用RSA签名方式
        AlipayClient client = new DefaultAlipayClient(PayConstants.AlipayGatewayURL, customer.getAppId(),
                customer.getSecret(), PayConstants.FormatJson, charset, customer.getSecret2(), PayConstants.AlipaySignTypeRSA2);
        AlipayTradeWapPayRequest alipay_request = new AlipayTradeWapPayRequest();

        // 封装请求支付信息
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo(order.getId().toString());
        model.setSubject(order.getBody());
        model.setTotalAmount(order.getTotalFee());
        model.setBody(order.getAttach());
        model.setProductCode("QUICK_MSECURITY_PAY");
        alipay_request.setBizModel(model);
        // 设置异步通知地址
        alipay_request.setNotifyUrl(alipayNotifyUrl);
        // 设置同步地址
        alipay_request.setReturnUrl(returnUrl);

        // form表单生产
        String form = "";
        try {
            // 调用SDK生成表单
            form = client.pageExecute(alipay_request).getBody();
            response.setContentType("text/html;charset=" + charset);
            response.getWriter().write(form);//直接将完整的表单html输出到页面
            response.getWriter().flush();
            response.getWriter().close();
        } catch (AlipayApiException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @RequestMapping("anon/alipay/notify")
    @ResponseBody
    public String alipayNotify(@RequestParam Map map, HttpServletResponse response) throws Exception {
        SortedMap<String, String> sortedMap = new TreeMap<>(map);

        String orderId = (String) map.get("out_trade_no");
        String total_fee = (String) map.get("total_amount");
        Order order = orderService.findOrderById(Long.valueOf(orderId));
        LogHelper.d(order.toString());
        LogHelper.d("totalfee " + total_fee);
        if (order == null || !Double.valueOf(order.getTotalFee()).equals(Double.valueOf(total_fee))) {
            LogHelper.d("订单不存在或金额不对!");
            return "failure";
        }

        PayCustomerSecret secret = orderService.findCustSecretByOrder(order);
        if (AlipaySignature.rsaCheckV1(sortedMap, secret.getSecret2(), charset, PayConstants.AlipaySignTypeRSA2)) {
            order.setOrderState(PayConstants.PAY_STATE_PAID);
            orderService.save(order);
            orderService.orderPayCallback(order);
            return "success";
        } else {
            LogHelper.e("验签失败!");
            return "failure";
        }

    }

    /**
     * 物业录入完成支付参数后用来测试支付的页面
     * @param request
     * @return
     */
    @RequestMapping("anon/payTest")
    String payTest(HttpServletRequest request,String appId,String user){
        String url = "/pages/mobile/property/payTest/payTest.html?user="+user;

        String jumpUrl = "redirect:"+wxPayService.getCompatibleUrlForWxAndAlipay(request,url,appId);
        LogHelper.d("jump : "+jumpUrl);
        return jumpUrl;
    }
}
